/*
                         \\\|///
                       \\  - -  //
                        (  @ @  )
+---------------------oOOo-(_)-oOOo----------------------+
|                                                        |
|                      MainWindow                    |
|                                                        |
|                       Thermofisher                     |
|                       Version v3.0                     |
|                       2021.03.24                       |
|                     Author:LiuMing                     |
|                                                        |
|                             Oooo                       |
+-----------------------oooO--(   )----------------------+
                       (   )   ) /
                        \ (   (_/
                         \_)


Log:
    FAN High Speed Voltage: 12v
    Regulator Max power out: 75%

*/

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTimer>
//#include <qDebug>
#include <QDebug>
#include <string>
#include <QDateTime>
#include <qserialportinfo.h>

#include <chrono>
#include <condition_variable>

#include <iostream>

#include <QFile>
#include <QFileDialog>

#include <thread>
#include <condition_variable>


#include <QSharedPointer>
#include <functional>


//void register_parse(); //process thread
//#include <mutex>

bool is_run = false;
std::mutex my_mutex;
std::condition_variable cv;  //cpp11 conditional variable

GlobalInfo glabalInfo;
quint16 GC_read_status = 2; //2     indicate unknown status  0:ready  1: Not-ready

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle(WINDOW_TITLE);

//    recvTick->moveToThread(register_parse);
//    recvTick = new QTimer();
//    recvTick->setInterval(50);
//    connect(recvTick,SIGNAL(timeout()),this,SLOT(recvTimeout()));

    //periodicTick = new QTimer();
   // std::shared_ptr<QTimer> periodicTick(new QTimer);
    periodicTick.reset(new QTimer); //smart point init mode-1

    periodicTick->setInterval(1000);
    connect(periodicTick.get(),SIGNAL(timeout()),this, SLOT(periodic_timeout()));
  //  connect(periodicTick,SIGNAL(timeout()),this, SLOT(periodic_timeout()));
    periodicTick->start(1000);

    timer_epc_mfc = std::make_shared<QTimer>();
    //timer_epc_mfc = new QTimer();
    timer_epc_mfc->setInterval(500);
    connect(timer_epc_mfc.get(),SIGNAL(timeout()),this, SLOT(epc_mfc_timeout()));
    timer_epc_mfc->start(1000);

    connect(this, &MainWindow::destroyed, this, &MainWindow::window_destroyed_handle);

    fillPortsInfo(SerDev_Mid);
    fillPortsInfo(SerDev_EPC_MFC);
    fillPortsInfo(SerDev_TEC_0);
    fillPortsInfo(SerDev_TEC_1);
    fillPortsInfo(SerDev_TEC_2);

    device_ID = 0x01;

//    mutex_midway = new QMutex();
//    mutex_epcmfc = new QMutex();
//    mutex_tec_1  = new QMutex();
//    mutex_tec_2  = new QMutex();
    mutex_midway = std::make_shared<QMutex>();
    mutex_epcmfc = std::make_shared<QMutex>();
    mutex_tec_1  = std::make_shared<QMutex>();
    mutex_tec_2  = std::make_shared<QMutex>();

    //qthread = new myThread();
    qthread = std::make_shared<myThread>();

    std::unique_ptr<std::thread> myPtr(new std::thread(std::bind(&MainWindow::thread_run,this)));
    std_thread = std::move(myPtr);
    if(std_thread->joinable())
        std_thread->detach();
    else
        qDebug()<<"std thread unjoinable... "<<endl;

    //QSharedPointer<QThread> ptr(qthread);


    connect(this, &myThread::destroyed,
            [this]()
            {
                 /* stop thread */
                qthread->quit();
                /* wait for thread finish processing */
                qthread->wait();
            }
    );

    connect(qthread.get(),  SIGNAL(sig_setValve(quint8 , quint16 )), this, SLOT(setValve(quint8 , quint16)));
    connect(qthread.get(),  SIGNAL(sig_setEPC(quint8 , float )), this, SLOT(setEPC(quint8 , float)));
    connect(qthread.get(),  SIGNAL(sig_setTEC(quint8 , float )), this, SLOT(setTEC(quint8 , float)));
    connect(qthread.get(),  SIGNAL(sig_setMFC(quint16 )), this, SLOT(setMFC(quint16)));
    connect(qthread.get(),  SIGNAL(sig_setHeater(quint8 , float)), this, SLOT(setHeater(quint8 , float)));
    connect(qthread.get(),  SIGNAL(sig_setHeatingTube(quint8 , float)), this, SLOT(setHeatingTube(quint8 , float)));
    connect(qthread.get(),  SIGNAL(sig_setGC(bool )), this, SLOT(setGC(bool)));
    connect(qthread.get(),  SIGNAL(sig_readGC_stus()), this, SLOT(readGC_stus()));

    connect(qthread.get(),  SIGNAL(sig_Initialization()), this, SLOT(Initialization()));
    connect(qthread.get(),  SIGNAL(sig_ReadEPC(quint8 )), this, SLOT(ReadEPC(quint8 )));
    connect(qthread.get(),  SIGNAL(sig_PurgeDehydration()), this, SLOT(PurgeDehydration()));
    connect(qthread.get(),  SIGNAL(sig_PurgeConcentrationA()), this, SLOT(PurgeConcentrationA()));
    connect(qthread.get(),  SIGNAL(sig_PurgeConcentrationB()), this, SLOT(PurgeConcentrationB()));
    connect(qthread.get(),  SIGNAL(sig_PurgeFocusing()), this, SLOT(PurgeFocusing()));
    connect(qthread.get(),  SIGNAL(sig_PreSampleA()), this, SLOT(PreSampleA()));
    connect(qthread.get(),  SIGNAL(sig_PreSampleB()), this, SLOT(PreSampleB()));
    connect(qthread.get(),  SIGNAL(sig_SampleA()), this, SLOT(SampleA()));
    connect(qthread.get(),  SIGNAL(sig_SampleB()), this, SLOT(SampleB()));
    connect(qthread.get(),  SIGNAL(sig_PrePurgeA()), this, SLOT(PrePurgeA()));
    connect(qthread.get(),  SIGNAL(sig_PrePurgeB()), this, SLOT(PrePurgeB()));
    connect(qthread.get(),  SIGNAL(sig_ConTrapFireA()), this, SLOT(ConTrapFireA()));
    connect(qthread.get(),  SIGNAL(sig_ConTrapFireB()), this, SLOT(ConTrapFireB()));
    connect(qthread.get(),  SIGNAL(sig_FocusTrapFire()), this, SLOT(FocusTrapFire()));
    connect(qthread.get(),  SIGNAL(sig_StandardA()), this, SLOT(StandardA()));
    connect(qthread.get(),  SIGNAL(sig_StandardB()), this, SLOT(StandardB()));
//    StandardB()

//    std::thread t1(&MainWindow::register_parse, this); //
//    //t1.join();
//    if(t1.joinable())
//        t1.detach();

    //connect(&t1,&MainWindow::sig_setValve, this, &MainWindow::slot_setValve);

    //setWindowFlags(Qt::FramelessWindowHint);
    //this->setAttribute(Qt::WA_TranslucentBackground);
    // this->setWindowFlags(Qt::FramelessWindowHint);
    on_comboBox_MFC_mode_currentIndexChanged(0); //For hide UI items
}

MainWindow::~MainWindow()
{
    delete ui;
    //delete uart;
    //delete recvTick;
   // delete periodicTick;
    //delete timer_epc_mfc;
  //  delete qthread;

//    delete mutex_midway;
//    delete mutex_epcmfc;
//    delete mutex_tec_1;
//    delete mutex_tec_2;

    qDebug()<<"MainWindow destruct"<<endl;
}




myThread::myThread(QObject *parent) : QThread(parent)
{
    /* Qthread构造函数 */
}




void MainWindow::window_destroyed_handle()
{

    qDebug()<<"window_destroyed"<<endl;
}

void MainWindow::fillPortsInfo(uint8_t whichPort)
{
    switch(whichPort)
    {
    case SerDev_Mid:
        ui->combCom_Mid->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QStringList list;
            list << info.portName();
            ui->combCom_Mid->addItem(list.first(), list);
        }
        break;
    case SerDev_EPC_MFC:
        ui->combCom_EPC->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QStringList list;
            list << info.portName();
            ui->combCom_EPC->addItem(list.first(), list);
        }
        break;
    case SerDev_TEC_0:
        ui->combCom_TEC0->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QStringList list;
            list << info.portName();
            ui->combCom_TEC0->addItem(list.first(), list);
        }
        break;
    case SerDev_TEC_1:
        ui->combCom_TEC1->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QStringList list;
            list << info.portName();
            ui->combCom_TEC1->addItem(list.first(), list);
        }
        break;
    case SerDev_TEC_2:
        ui->combCom_TEC2->clear();
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            QStringList list;
            list << info.portName();
            ui->combCom_TEC2->addItem(list.first(), list);
        }
        break;
    }
}
void MainWindow::checkPortsInfo(uint8_t whichPort)
{
    fillPortsInfo(whichPort);
    switch(whichPort)
    {
    case SerDev_Mid:
        ui->combCom_Mid->setCurrentText(comPort);
        break;
    case SerDev_EPC_MFC:
        ui->combCom_EPC->setCurrentText(comPort);
        break;
    case SerDev_TEC_1:
        ui->combCom_TEC1->setCurrentText(comPort);
        break;
    case SerDev_TEC_2:
        ui->combCom_TEC2->setCurrentText(comPort);
        break;
    }
}
void MainWindow::on_refresh_com_Mid_sliderPressed()
{
    qDebug()<<"Mid refresh com"<<endl;
    checkPortsInfo(SerDev_Mid);
}
void MainWindow::on_refresh_com_EPC_sliderPressed()
{
    qDebug()<<"EPC refresh com"<<endl;
    checkPortsInfo(SerDev_EPC_MFC);
}

void MainWindow::on_refresh_com_TEC_0_sliderPressed()
{
    qDebug()<<"TEC0 refresh com"<<endl;
    checkPortsInfo(SerDev_TEC_0);
}
void MainWindow::on_refresh_com_TEC_1_sliderPressed()
{
    qDebug()<<"TEC1 refresh com"<<endl;
    checkPortsInfo(SerDev_TEC_1);
}
void MainWindow::on_refresh_com_TEC_sliderPressed()
{
    qDebug()<<"TEC2 refresh com"<<endl;
    checkPortsInfo(SerDev_TEC_2);
}



//void MainWindow::handleError(QSerialPort::SerialPortError error)
//{
//    switch (error)
//    {
//        case QSerialPort::ResourceError:
//        {
//            uart->close();
//            ui->BT_Connect_Mid->setText("打开");
//            //log(tr("系统 <- 串口设备已拔出"));
//        }
//        default:
//            break;
//    }
//}
void MainWindow::Log(QString str)
{
    ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+str);
}

QString MainWindow::hexString2QString( uint8_t *buff, int16_t len)
{
        QString logStr;
        while (len--)
        {
            uint8_t u8 = *buff++;
            logStr += QString("%1").arg((u8 >> 4) & 0x0F, 0, 16).toUpper();
            logStr += QString("%1").arg(u8 & 0x0F,0, 16).toUpper();
        }

        return logStr;
}

void  MainWindow::MainWindow_log(uint8_t *buf, int buf_Len)
{
    ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> " + hexString2QString(buf, buf_Len));
}
void  MainWindow::MainWindow_log(char *buf)
{
    ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> " + QString(buf));
}


//void MainWindow::uartSend(unsigned char *buf,int buf_Len)
//{

//    if(uart->isOpen())
//    {
//        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX->" + hexString2QString(buf, buf_Len));
//        uart->write((char *)buf, buf_Len);
//    }
//    else
//    {
//        qDebug()<<"UART Not opened\n"<<endl;
//        ui->statusBar->showMessage("UART Not opened");
//    }
//}

//void MainWindow::recv_handler()
//{
//    if(uart->bytesAvailable())
//    {
//        recvArr += uart->readAll();
//        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"R->" + recvArr.toHex());
//        recvTick->start(50); //20ms timeout
//    }
//}

//void MainWindow::recvTimeout()
//{
//    recvTick->stop();
//    int BuffLen = recvArr.length();

//    if(BuffLen > UART_BUFFER_MAX)
//    {
//        BuffLen = UART_BUFFER_MAX;
//    }

//    memset(recvBuf, 0, sizeof(recvBuf));
//    memcpy(recvBuf,recvArr,BuffLen);
//    recvArr.clear();

////    cv.notify_one(); //release semaphore
////    qDebug()<<"接球"<<endl;
//}



/*--------------------------- User Code -----------------------------*/


void MainWindow::on_BT_Connect_Mid_clicked()
{
    if(!Midway_isOpened)
    {
        comPort = ui->combCom_Mid->currentText();
        bool status = tf_modbusDeviceHandle(SerDev_Mid,Midway_isOpened, comPort);

        if(status)
        {
            Midway_isOpened = true;
            ui->BT_Connect_Mid->setText("disconnect");
        }
    }
    else
    {
            Midway_isOpened = false;
            tf_modbus_close(SerDev_Mid);
            ui->BT_Connect_Mid->setText("connect");
    }
}
void MainWindow::on_BT_Connect_EPC_MFC_clicked() //epc & mfc
{
    if(!EPC_MFC_isOpened)
    {
        comPort = ui->combCom_EPC->currentText();
        bool status = tf_modbusDeviceHandle(SerDev_EPC_MFC,EPC_MFC_isOpened, comPort);

        if(status)
        {
            EPC_MFC_isOpened = true;
            ui->BT_Connect_EPC_MFC->setText("disconnect");
        }
    }
    else
    {
            EPC_MFC_isOpened = false;
            tf_modbus_close(SerDev_EPC_MFC);
            ui->BT_Connect_EPC_MFC->setText("connect");
    }
}

void MainWindow::on_BT_Connect_TEC_0_clicked()
{
    if(!TEC_0_isOpened)
    {
        comPort = ui->combCom_TEC0->currentText();
        bool status = tf_modbusDeviceHandle(SerDev_TEC_0,TEC_0_isOpened, comPort);

        if(status)
        {
            TEC_0_isOpened = true;
            ui->BT_Connect_TEC_0->setText("disconnect");
        }
    }
    else
    {
            TEC_0_isOpened = false;
            tf_modbus_close(SerDev_TEC_0);
            ui->BT_Connect_TEC_0->setText("connect");
    }
}
void MainWindow::on_BT_Connect_TEC_1_clicked()
{
    if(!TEC_1_isOpened)
    {
        comPort = ui->combCom_TEC1->currentText();
        bool status = tf_modbusDeviceHandle(SerDev_TEC_1,TEC_1_isOpened, comPort);

        if(status)
        {
            TEC_1_isOpened = true;
            ui->BT_Connect_TEC_1->setText("disconnect");
        }
    }
    else
    {
            TEC_1_isOpened = false;
            tf_modbus_close(SerDev_TEC_1);
            ui->BT_Connect_TEC_1->setText("connect");
    }
}

void MainWindow::on_BT_Connect_TEC_2_clicked()
{
    if(!TEC_2_isOpened)
    {
        comPort = ui->combCom_TEC2->currentText();
        bool status = tf_modbusDeviceHandle(SerDev_TEC_2,TEC_2_isOpened, comPort);

        if(status)
        {
            TEC_2_isOpened = true;
            ui->BT_Connect_TEC_2->setText("disconnect");
        }
    }
    else
    {
        TEC_2_isOpened = false;
        tf_modbus_close(SerDev_TEC_2);
        ui->BT_Connect_TEC_2->setText("connect");

        periodicTick->stop(); //close read TEC temp
    }
}

void MainWindow::on_BT_clearLog_clicked()
{
    ui->TxtLog->clear();
}


/***************************************** MFC Area *********************************************/

void MainWindow::on_comboBox_MFC_mode_currentIndexChanged(int index)
{
    /*
        Note:
        MFC_type = 0 : default MFC , RS485's ID = 0x01
        MFC_type = 1 : SevenStar MFC, RS485's ID = 0x20
    */
    MFC_type = index;
    qDebug()<<"index= "<<index<<endl;

    /* 修改字符串0~500 -> 0-200 */
    switch(MFC_type)
    {
        case 0:
            ui->label_5->setText(" 输入 范围：(0-500 sccm)");
            ui->lineEdit_MFC_setFlow_2->hide();
            ui->BT_MFC_setFlow_2->hide();
            ui->label_21->hide();
            ui->label_MFC_flowVal_2->hide();
        break;

        case 1:  //SevenStar
            ui->label_5->setText(" 输入 范围：(0-200 mL/min)");

            ui->lineEdit_MFC_setFlow_2->show();
            ui->BT_MFC_setFlow_2->show();
            ui->label_21->show();
            ui->label_MFC_flowVal_2->show();
        break;
    }
}


void MainWindow::on_BT_MFC_setFlow_clicked()
{

    int set_flow_val = 0;
    set_flow_val = ui->lineEdit_MFC_setFlow->text().toInt();
    quint16 SERVER_ADDR;

    switch(MFC_type)
    {
        case 0:
            if(set_flow_val<0 || set_flow_val>500)
            {
                ui->statusBar->showMessage("输入范围超出[0,500] sccm",2000);
                return ;
            }

            SERVER_ADDR = 0x31;
            set_flow_val *= 10; //0-5000 数字量 对应 0~500 sccm
            sendWriteHoldingReg(SerDev_EPC_MFC,MFC_MB_SLAVE_ID,SERVER_ADDR, (quint16) set_flow_val);

        break;

        case 1:  //SevenStar
            if(set_flow_val<0 || set_flow_val>200) //MARKK
            {
                ui->statusBar->showMessage("输入范围超出[0,200] mL/min",2000);
                return ;
            }

            set_flow_val = (set_flow_val * (49152-16384) / 200 + 16384); //details see <CS系列产品研华MODBUS协议1.1>
            SERVER_ADDR = 0x0002; //SevenStar MFC's MB address
            sendWriteHoldingReg(SerDev_EPC_MFC,MFC_SEVEN_SLAVE_ID,SERVER_ADDR, (quint16) set_flow_val);

        break;
    }
}
void MainWindow::on_BT_MFC_setFlow_2_clicked() //#2 MFC clicked
{

    int set_flow_val = 0;
    set_flow_val = ui->lineEdit_MFC_setFlow_2->text().toInt();
    quint16 SERVER_ADDR;

    if(set_flow_val<0 || set_flow_val>200) //MARKK
    {
        ui->statusBar->showMessage("输入范围超出[0,200] mL/min",2000);
        return ;
    }

    set_flow_val = (set_flow_val * (49152-16384) / 200 + 16384); //details see <CS系列产品研华MODBUS协议1.1>
    SERVER_ADDR = 0x0002; //SevenStar MFC's MB address
    sendWriteHoldingReg(SerDev_EPC_MFC,MFC_SEVEN_SLAVE_ID_2,SERVER_ADDR, (quint16) set_flow_val);
}


void MainWindow::epc_mfc_timeout() //1s
{
    static int epc_mfc_read_which = 0;
    epc_mfc_read_which++;

        /* time slice */
    if(epc_mfc_read_which%2==0) //read EPC
    {
        if(epc_read_status)
        {
           #define REG_FLOAT_NUM 3
           quint16 EPCFLOW_START_ADDR = 0x00;
            float epc_flow_read_buf[3];

            if(epc_mode_index) //flow mode
            {
                EPCFLOW_START_ADDR = 6;
                qDebug()<<"EPC flow mode"<<endl;
            }
            else //press mode
            {
                EPCFLOW_START_ADDR = 0;
                qDebug()<<"EPC press mode"<<endl;
            }

            mutex_epcmfc->lock();
            uint8_t ret = sendReadMultiFloatReg(SerDev_EPC_MFC,EPC_MB_SLAVE_ID,epc_flow_read_buf, EPCFLOW_START_ADDR, REG_FLOAT_NUM);
            mutex_epcmfc->unlock();
            //qDebug()<<"sendReadMultiFloatReg: " <<ret<<endl;
              // cur_flow = sendReadHoldingReg(SerDev_EPC_MFC,SLAVE_ID_MFC,ADDR_READ_EPC_FLOW);
            if(!epc_mode_index) {
                ui->label_EPC_flow_1->setText(QString::number(epc_flow_read_buf[0],'f',2) + " kPa");
                ui->label_EPC_flow_2->setText(QString::number(epc_flow_read_buf[1],'f',2) + " kPa");
                ui->label_EPC_flow_3->setText(QString::number(epc_flow_read_buf[2],'f',2) + " kPa");
            } else {
                ui->label_EPC_flow_1->setText(QString::number(epc_flow_read_buf[0],'f',2) + " sccm");
                ui->label_EPC_flow_2->setText(QString::number(epc_flow_read_buf[1],'f',2) + " sccm");
                ui->label_EPC_flow_3->setText(QString::number(epc_flow_read_buf[2],'f',2) + " sccm");
            }
        }

        if(GC_readStatus)  //LM add@2021-05-06
        {
            quint16 addr_GC_read_status = 14;

            mutex_epcmfc->lock();
            GC_read_status = sendReadHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_GC_read_status);
            mutex_epcmfc->unlock();
            qDebug()<<"GC_read_status: "<<GC_read_status<<endl;
            switch(GC_read_status)
            {
             case 0:
                ui->label_GCstatus->setText("ready");
                break;
             case 1:
               ui->label_GCstatus->setText("not-ready");
                break;
            default:
                ui->label_GCstatus->setText("unkonwn");
            }
        }
    }
    else //read MFC
    {
        if(mfc_read_status)
        {
            uint16_t cur_flow = 0;
            uint16_t ADDR_READ_CUR_FLOW = 0x01;
            float mfc_flow = 0;

            switch (MFC_type) {
                case 0: //default MFC
                   ADDR_READ_CUR_FLOW = 0x01;
                   mutex_epcmfc->lock();
                   cur_flow = sendReadHoldingReg(SerDev_EPC_MFC,MFC_MB_SLAVE_ID,ADDR_READ_CUR_FLOW);
                   mutex_epcmfc->unlock();
                   if(cur_flow<=0 || cur_flow >= 0xfffd)
                   {
                       cur_flow = 0;
                       mfc_flow = 0;
                   }
                   else
                   {
                       qDebug()<<"cur_flow_1 = "<<hex<<cur_flow<<endl;
                        mfc_flow = (float)cur_flow / 10;
                   }

                   ui->label_MFC_flowVal->setText( QString::number(mfc_flow,'f', 2) + "sccm");
                   qDebug()<<"mfc read 1s"<<endl;
                    break;

                case 1: //SevenStar MFC
                    ADDR_READ_CUR_FLOW = 0x0003;
                    mutex_epcmfc->lock();


                    //Read #1 MFC
                    cur_flow = sendReadHoldingReg(SerDev_EPC_MFC,MFC_SEVEN_SLAVE_ID,ADDR_READ_CUR_FLOW);
                    mutex_epcmfc->unlock();
                    if(cur_flow<=0 || cur_flow >= 0xfffd)
                    {
                        cur_flow = 0;
                        mfc_flow = 0;
                    }
                    else
                    {
                        qDebug()<<"cur_flow = "<<hex<<cur_flow<<endl;
                        mfc_flow = (float)(cur_flow-0x4000) * 200 / (49152-16384) ;
                    }
                    //float mfc_flow = (float)cur_flow / 10;
                    ui->label_MFC_flowVal->setText( QString::number(mfc_flow,'f', 2) + " mL/min");

                    //Read #2 MFC
                    mutex_epcmfc->lock();
                    cur_flow = sendReadHoldingReg(SerDev_EPC_MFC,MFC_SEVEN_SLAVE_ID_2,ADDR_READ_CUR_FLOW);
                    mutex_epcmfc->unlock();
                    if(cur_flow<=0 || cur_flow >= 0xfffd)
                    {
                        cur_flow = 0;
                        mfc_flow = 0;
                    }
                    else
                    {
                        qDebug()<<"cur_flow = "<<hex<<cur_flow<<endl;
                        mfc_flow = (float)(cur_flow-0x4000) * 200 / (49152-16384) ;
                    }
                    //float mfc_flow = (float)cur_flow / 10;
                    ui->label_MFC_flowVal_2->setText( QString::number(mfc_flow,'f', 2) + " mL/min");

                    /* TEST readout MFC set val */
                    cur_flow = sendReadHoldingReg(SerDev_EPC_MFC,MFC_SEVEN_SLAVE_ID,0x02);
                    qDebug()<<"set Val = "<<(float)(cur_flow-0x4000)*200/(49152-16384) <<endl;

                    break;
                default:
                    qDebug()<<"MFC_type err"<<endl;
                break;

            }

        }
    }
}

void MainWindow::on_checkBox_ContinueRead_MFC_clicked(bool checked)
{
    qDebug()<<checked<<endl;
    if(checked) //periodic read TEC temp
    {
        mfc_read_status = 1;
    }
    else
    {
        mfc_read_status = 0;
    }
}

/*++++++++++++++++++++++++++++++++++++++ TEC 1~2 Area ++++++++++++++++++++++++++++++++++++++++++*/

void MainWindow::periodic_timeout() //1.5s  LMARK
{
    if(TEC_0_read_status)
    {
        char *str_read_temp = "$R100?\r\n";
        //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
        int ret;
        if((ret=serialWirte(SerDev_TEC_0, str_read_temp, strlen(str_read_temp)))==0)
            MainWindow_log(str_read_temp);

        delay(100);

        if(SerDevice[SerDev_TEC_0]->bytesAvailable())
        {
            recvArr += SerDevice[SerDev_TEC_0]->readAll();
            QString str = recvArr;
            str = str.right(17).left(13); //从倒数第17个开始截取，截取长度13个
            float tec_temp = str.toFloat();
            str = QString::number(tec_temp,'f',2);
            str += " °C";
            ui->label_tec_0_temp->setText(str);
            //qDebug()<<str.toFloat()<<endl;

            //qDebug()<<str<<endl;
            recvArr.clear();
        }
    }

    if(TEC_1_read_status)
    {
        char *str_read_temp = "$R100?\r\n";
        //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
        int ret;
        if((ret=serialWirte(SerDev_TEC_1, str_read_temp, strlen(str_read_temp)))==0)
            MainWindow_log(str_read_temp);

        delay(100);

        if(SerDevice[SerDev_TEC_1]->bytesAvailable())
        {
            recvArr += SerDevice[SerDev_TEC_1]->readAll();
            //recvArr += SerDevice[SerDev_TEC]->readAll();
            QString str = recvArr;
            str = str.right(17).left(13); //从倒数第17个开始截取，截取长度13个
            float tec_temp = str.toFloat();
            str = QString::number(tec_temp,'f',2);
            str += " °C";
            ui->label_tec1_temp->setText(str);
            //qDebug()<<str.toFloat()<<endl;

            //qDebug()<<str<<endl;
            recvArr.clear();
        }
    }

    if(TEC_2_read_status)
    {
        char *str_read_temp = "$R100?\r\n";
        //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
        int ret;
        if((ret=serialWirte(SerDev_TEC_2, str_read_temp, strlen(str_read_temp)))==0)
            MainWindow_log(str_read_temp);

        delay(100);

        if(SerDevice[SerDev_TEC_2]->bytesAvailable())
        {
            recvArr += SerDevice[SerDev_TEC_2]->readAll();
            //recvArr += SerDevice[SerDev_TEC]->readAll();
            QString str = recvArr;
            str = str.right(17).left(13); //从倒数第17个开始截取，截取长度13个
            float tec_temp = str.toFloat();
            str = QString::number(tec_temp,'f',2);
            str += " °C";
            ui->label_tec_2_temp->setText(str);
            //qDebug()<<str.toFloat()<<endl;

            //qDebug()<<str<<endl;
            recvArr.clear();
        }
    }

    if(HotLine_readStus) //read HotLine Midway board temp
    {
        float HeaterTubeTemp[2] ={ 0};
        sendReadMultiFloatReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID, HeaterTubeTemp, addr_Mid_readGCTemp, 2);
        ui->label_GC_HotLineTemp->setText(QString::number(HeaterTubeTemp[1] ,'f', 2)+" °C");
        ui->label_Transfer_HotLineTemp->setText(QString::number(HeaterTubeTemp[0] ,'f', 2)+" °C");
    }


}

/*—————————————————— 除水 TEC0 ————————————————————————————*/
void MainWindow::on_BT_TEC_0_start_clicked()
{
    qDebug()<<"tec0 start"<<endl;
    char *str = "$W\r\n";
    //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_0, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_BT_TEC_0_stop_clicked()
{
    qDebug()<<"tec0 stop"<<endl;
    char *str = "$Q\r\n";
   // serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_0, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_checkBox_ContinueRead_TEC0_clicked(bool checked)
{
    qDebug()<<checked<<endl;
    if(checked) //periodic read TEC temp
    {
        TEC_0_read_status = 1;
        periodicTick->start(1000);
    }
    else
    {
        TEC_0_read_status = 0;
    }
}

void MainWindow::on_BT_TEC_0_setT_clicked()
{
    if(ui->lineEdit_TEC_0_setT->text() == NULL)
    {
        qDebug()<<"TEC0 no input"<<endl;
        return;
    }
    setTEC(0, ui->lineEdit_TEC_0_setT->text());
 //   qDebug()<<"LM ->"<<str_setTemp<<endl;
}
/*____________________________________________________*/

void MainWindow::on_BT_TEC1_start_clicked()
{
    qDebug()<<"tec start"<<endl;
    char *str = "$W\r\n";
    //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_1, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_BT_TEC1_stop_clicked()
{
    qDebug()<<"tec stop"<<endl;
    char *str = "$Q\r\n";
   // serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_1, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_BT_TEC1_setT_clicked()
{
    if(ui->lineEdit_TEC1_setT->text() == NULL)
    {
        qDebug()<<"TEC1 no input"<<endl;
        return;
    }

    QString str = ui->lineEdit_TEC1_setT->text();
    qDebug()<<str<<endl;
    setTEC(1, str);
 //   qDebug()<<"LM ->"<<str_setTemp<<endl;
}
void MainWindow::on_checkBox_ContinueRead_TEC_1_clicked(bool checked)
{
    qDebug()<<checked<<endl;
    if(checked) //periodic read TEC temp
    {
        //periodicTick->start(1000);
        TEC_1_read_status = 1;
        periodicTick->start(1000);

    }
    else
    {
        //periodicTick->stop();
        TEC_1_read_status = 0;
    }
}
/*____________________________________________________*/

void MainWindow::on_BT_TEC_2_start_clicked()
{
    qDebug()<<"tec start"<<endl;
    char *str = "$W\r\n";
    //serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_2, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_BT_TEC_2_stop_clicked()
{
    qDebug()<<"tec stop"<<endl;
    char *str = "$Q\r\n";
   // serialWirte(SerDev_TEC, str_read_temp, strlen(str_read_temp));
    int ret;
    if((ret=serialWirte(SerDev_TEC_2, str, strlen(str)))==0)
        MainWindow_log(str);
}

void MainWindow::on_checkBox_ContinueRead_TEC2_clicked(bool checked)
{
    qDebug()<<checked<<endl;
    if(checked) //periodic read TEC temp
    {
        TEC_2_read_status = 1;
        periodicTick->start(1000);
    }
    else
    {
        TEC_2_read_status = 0;
    }
}

void MainWindow::on_BT_TEC_2_setT_clicked()
{
#if 0
    QString TEC_temp = "$R0=";
    TEC_temp += ui->lineEdit_TEC_2_setT->text();
    TEC_temp += "\r\n";
    QByteArray ba = TEC_temp.toLatin1();
    char *str_setTemp = ba.data();
    int ret;
    if((ret=serialWirte(SerDev_TEC_2, str_setTemp, strlen(str_setTemp)))==0)
        MainWindow_log(str_setTemp);
#endif

    if(ui->lineEdit_TEC_2_setT->text() == NULL)
    {
        qDebug()<<"TEC2 no input"<<endl;
        return;
    }
    setTEC(2, ui->lineEdit_TEC_2_setT->text());
 //   qDebug()<<"LM ->"<<str_setTemp<<endl;
}



void MainWindow::on_checkBox_valve_1_clicked(bool checked)
{
//#define valve_addr_1 1544
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_1, 1);
        setValve(1, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #1 ON,  MB addr: 1544");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_1, 0);
        setValve(1, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #1 OFF, MB addr: 1544");
    }
}

void MainWindow::on_checkBox_valve_2_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_2 1545
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_2, 1);
        setValve(2, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #2 ON,  MB addr: 1545");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_2, 0);
        setValve(2, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #2 OFF, MB addr: 1545");
    }
}

void MainWindow::on_checkBox_valve_3_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_3 1546
    if(checked)
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_3, 1);
        setValve(3, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #3 ON,  MB addr: 1546");
    }
    else
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_3, 0);
        setValve(3, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #3 OFF, MB addr: 1546");
    }
}

void MainWindow::on_checkBox_valve_4_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_4 1547
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_4, 1);
        setValve(4, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #4 ON,  MB addr: 1547");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_4, 0);
        setValve(4, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #4 OFF, MB addr: 1547");
    }
}

void MainWindow::on_checkBox_valve_5_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_5 1548
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_5, 1);
        setValve(5, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #5 ON,  MB addr: 1548");
    }
    else
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_5, 0);
        setValve(5, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #5 OFF, MB addr: 1548");
    }
}

void MainWindow::on_checkBox_valve_6_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_6 1549
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_6, 1);
        setValve(6, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #6 ON,  MB addr: 1549");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_6, 0);
        setValve(6, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #6 OFF, MB addr: 1549");
    }
}

void MainWindow::on_checkBox_valve_7_clicked(bool checked)
{
//#define slave_ID 0x01
//#define valve_addr_7 1550
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_7, 1);
        setValve(7, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Valve #7 ON,  MB addr: 1550");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_7, 0);
        setValve(7, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> Pump #7 OFF, MB addr: 1550");
    }
}

void MainWindow::on_checkBox_valve_8_clicked(bool checked)
{
    if(checked)
    {
       // sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_7, 1);
        setValve(8, 1);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> ERV2 #8 ON,  MB addr: 1551");
    }
    else
    {
        //sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,valve_addr_7, 0);
        setValve(8, 0);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"TX-> ERV2 #8 OFF, MB addr: 1551");
    }
}

/************************************ EPC Area ***********************************/
void MainWindow::on_comboBox_EPC_mode_currentIndexChanged(int index)
{
    epc_mode_index = index;
    if(epc_mode_index)
    {
        qDebug()<<"EPC set Flow mode"<<endl;
        ui->label_EPC_flow_1->setText("0 sccm");
        ui->label_EPC_flow_2->setText("0 sccm");
        ui->label_EPC_flow_3->setText("0 sccm");
        ui->label_2->setText("0~100 sccm");
        ui->label_6->setText("0~500 sccm");
        ui->label_7->setText("0~100 sccm");

        /* send 切换EPC模式的CMD */
        sendWriteHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID,2050, 1);
    }
    else
    {
        qDebug()<<"EPC set Press mode"<<endl;
        ui->label_EPC_flow_1->setText("0 kPa");
        ui->label_EPC_flow_2->setText("0 kPa");
        ui->label_EPC_flow_3->setText("0 kPa");
        ui->label_2->setText("0~380 kPa");
        ui->label_6->setText("0~380 kPa");
        ui->label_7->setText("0~380 kPa");

        /* send 切换EPC模式的CMD */
        sendWriteHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID,2050, 0);
    }
}

void MainWindow::on_BT_EPC_setFlow_1_clicked()
{
    QString str = ui->lineEdit_EPC_setFlow_1->text();
    float num = str.toFloat();

    if(!epc_mode_index)
    {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_EPC_Press_channel_1, num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Press-1, addr: 1557");
    } else {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, (addr_EPC_Press_channel_1+2), num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Flow-1, addr: 1559");
    }
}

void MainWindow::on_BT_EPC_setFlow_2_clicked()
{

    //QString str = ui->lineEdit_EPC_setFlow_2->text();
    float num = ui->lineEdit_EPC_setFlow_2->text().toFloat();
    qDebug()<<"setFlow_2"<<num<<endl;

    if(!epc_mode_index)
    {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_EPC_Press_channel_2, num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Press-2, addr: 1561");
    } else {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, (addr_EPC_Press_channel_2+2), num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Flow-2, addr: 1563");
    }
}

void MainWindow::on_BT_EPC_setFlow_3_clicked()
{

    QString str = ui->lineEdit_EPC_setFlow_3->text();
    float num = str.toFloat();

    if(!epc_mode_index)
    {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_EPC_Press_channel_3, num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Press-3, addr: 1565");
    } else {
        sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, (addr_EPC_Press_channel_3+2), num);
        ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"EPC-> set Flow-3, addr: 1567");
    }
}

void MainWindow::on_checkBox_ContinueRead_EPC_clicked(bool checked)
{
    if(checked)
    {
        epc_read_status = 1;
    }
    else
    {
        epc_read_status = 0;
    }
}


void MainWindow::on_BT_GC_ON_clicked()
{
    quint16 addr_GC_Triger_In = 1544;
//    quint16 addr_GC_read_status = 14;
//    quint16 GC_read_status = 2; //2 indicate unknown status

    mutex_epcmfc->lock();
    sendWriteHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_GC_Triger_In, 1);
    mutex_epcmfc->unlock();
//    delay(500);

//    GC_read_status = sendReadHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_GC_read_status);
//    qDebug()<<"GC_read_status: "<<GC_read_status<<endl;
//    switch(GC_read_status)
//    {
//     case 0:
//        ui->label_GCstatus->setText("ready");
//        break;
//     case 1:
//       ui->label_GCstatus->setText("no-ready");
//        break;
//    default:
//        ui->label_GCstatus->setText("unkonwn");
//        break;
//    }
}

void MainWindow::on_BT_GC_OFF_clicked()
{
    quint16 addr_GC_Triger_In = 1544;
//    quint16 addr_GC_read_status = 14;
//    quint16 GC_read_status = 2; //2 indicate unknown status

    mutex_epcmfc->lock();
    sendWriteHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_GC_Triger_In, 0);
    mutex_epcmfc->unlock();
//    delay(500);

//    GC_read_status = sendReadHoldingReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, addr_GC_read_status);
//    qDebug()<<"GC_read_status: "<<GC_read_status<<endl;
//    switch(GC_read_status)
//    {
//     case 0:
//        ui->label_GCstatus->setText("ready");
//        break;
//     case 1:
//       ui->label_GCstatus->setText("no-ready");
//        break;
//    default:
//        ui->label_GCstatus->setText("unkonwn");
//    }
}

void MainWindow::on_checkBox_ContinueRead_GC_clicked(bool checked)
{
    if(checked)
    {
        GC_readStatus = true;
    } else {
        GC_readStatus = false;
    }
}



/**************************** Heater Area *************************************/
void MainWindow::on_horizontalSlider_A_sliderMoved(int position)
{
    ui->label_heater0_dig->setText(QString::number(position));

    ui->label_heater0_tim->setText(QString::number((position*0.05),'f',2) + " s");

}

void MainWindow::on_horizontalSlider_B_sliderMoved(int position)
{
    ui->label_heater1_dig->setText(QString::number(position));

    ui->label_heater1_tim->setText(QString::number((position*0.05),'f',2) + " s");
}


void MainWindow::on_BT_setTimHeate_A_clicked()
{
    uint16_t sendBuf[2];

    sendBuf[0] = 1;
    sendBuf[1] = ui->horizontalSlider_A->value();
    sendWriteMultiHoldingReg(SerDev_Mid,0x01,sendBuf, addr_Mid_Heater0_UMB_ON, 2);
}

void MainWindow::on_BT_setTimHeate_B_clicked()
{
    uint16_t sendBuf[2];

    sendBuf[0] = 1;
    sendBuf[1] = ui->horizontalSlider_B->value();
    sendWriteMultiHoldingReg(SerDev_Mid,0x01,sendBuf, addr_Mid_Heater1_ProBlo_ON, 2);
}

void MainWindow::on_horizontalSlider_C_sliderMoved(int position)
{
    ui->label_heater2_dig->setText(QString::number(position));

    ui->label_heater2_tim->setText(QString::number((position*0.05),'f',2) + " s");
}

void MainWindow::on_horizontalSlider_D_sliderMoved(int position)
{
    ui->label_heater3_dig->setText(QString::number(position));

    ui->label_heater3_tim->setText(QString::number((position*0.05),'f',2) + " s");
}

void MainWindow::on_BT_setTimHeate_C_clicked()
{
    uint16_t sendBuf[2];

    sendBuf[0] = 1;
    sendBuf[1] = ui->horizontalSlider_C->value();
    sendWriteMultiHoldingReg(SerDev_Mid,0x01,sendBuf, addr_Mid_Heater2_ProFil_ON, 2);
}

void MainWindow::on_BT_setTimHeate_D_clicked()
{
    uint16_t sendBuf[2];

    sendBuf[0] = 1;
    sendBuf[1] = ui->horizontalSlider_D->value();
    sendWriteMultiHoldingReg(SerDev_Mid,0x01,sendBuf, addr_Mid_Heater3_Sting_ON, 2);
}



/*----------------- Transfer HotLine --------------*/
void MainWindow::on_BT_TransferHotLine_setT_clicked()
{
    if(ui->lineEdit_TransferHotLine_Temp->text() == NULL)
    {
        qDebug()<<"TransferHotLine_setT not input"<<endl;
        return;
    }
    float temp = ui->lineEdit_TransferHotLine_Temp->text().toFloat();
    setHeatingTube(0, temp);
    Log("TransferHotLine set "+ui->lineEdit_TransferHotLine_Temp->text()+" °C");
}
void MainWindow::on_checkBox_ContinueRead_transfer_hotline_clicked(bool checked) //periodic_timeout
{
    qDebug()<<checked<<endl;
    if(checked) //periodic read TEC temp
    {
        HotLine_readStus = 1;
        periodicTick->start(1000);
    }
    else
    {
        HotLine_readStus = 0;
    }
}
/*---------------------- GC HotLine ---------------------------------*/
void MainWindow::on_BT_GCHotLine_setT_clicked()
{
    if(ui->lineEdit_GCHotLine_Temp->text() == NULL)
    {
        qDebug()<<"GCHotLine_setT not input"<<endl;
        return;
    }
    float temp = ui->lineEdit_GCHotLine_Temp->text().toFloat();
    setHeatingTube(1, temp);
    Log("GCHotLine set "+ui->lineEdit_GCHotLine_Temp->text()+" °C");
}



/***************** Parse FangJun's script **************************/
void MainWindow::on_BT_openScript_clicked()
{
    QString path = QFileDialog::getOpenFileName(this,"open","./Script/","TXT(*.txt)");

        if(path.isEmpty() == false)
        {
            //文件对象
            QFile file(path);
            bool isOK = file.open(QIODevice::ReadOnly); //只读打开
            if(isOK)
            {
                ui->TxtLog->append("配置脚本文件打开成功");
                //读文件  默认只识别 UTF-8
    #if 0
                QByteArray array = file.readAll();
                ui->TxtLog->setText(QString(array));
    #endif
                int ScriptLineNum = 0;
                QByteArray array;
                QString str,num0,num1;
                int whichStr = 0; //1:"Set EPC" 2:Set Valve 3:Set Trap  4:Set MFC  5: Set Heater 6: Hotline
                QStringList list;

                int channel_num,valve_status; //Set Valve 1 to Status 0
                float EPC_SV;



                while(file.atEnd() == false)
                {
                   array = file.readLine();  //memcpy(recvBuf,recvArr,BuffLen);
                   ScriptLineNum++;
                   str = array;
                   array.clear();//
                   //qDebug()<<str<<endl;

                   if(str.contains("Set EPC",Qt::CaseSensitive))
                       whichStr = 1;
                   else if(str.contains("Set Valve",Qt::CaseSensitive))
                       whichStr = 2;
                   else if(str.contains("Set Trap",Qt::CaseSensitive))
                       whichStr = 3;
                   else if(str.contains("Set MFC",Qt::CaseSensitive))
                       whichStr = 4;
                   else if(str.contains("Set Heater",Qt::CaseSensitive))
                       whichStr = 5;
                   else if(str.contains("Hotline",Qt::CaseSensitive))
                       whichStr = 6;

                   switch(whichStr)
                   {
                   case 1: //Set EPC 0 to 0 psi
                       list = str.split(" ");
                       num0 = list[2];
                       num1 = list[4];
                       //qDebug()<<num0<<num1<<endl;
                       channel_num = num0.toInt();
                            EPC_SV = num1.toFloat();

                        if(channel_num<0 || channel_num>2 || EPC_SV<0 || EPC_SV>400)
                        {
                            ui->TxtLog->append("脚本第" +  QString::number(ScriptLineNum) + "行解析错误: " + "EPC_Channel: "+num0+ "   EPC_set_value: "+num1);
                            break;
                        }

                       sendWriteFloatReg(SerDev_EPC_MFC, EPC_MB_SLAVE_ID, (addr_EPC_Press_channel_1+channel_num*4), EPC_SV);
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set EPC "+ num0 +" to "+ num1+" kPa");
                       break;
                   case 2: //Set Valve 1 to Status 0
                       list = str.split(" ");
                       num0 = list[2];
                       num1 = list[5];
                       //qDebug()<<num0<<num1<<endl;

                       channel_num = num0.toInt();
                       valve_status = num1.toInt();

                       if(channel_num<1 || channel_num>8 || valve_status<0 || valve_status>1)
                       {
                           ui->TxtLog->append("脚本第" +  QString::number(ScriptLineNum) + "行解析错误: " + "valve_num: "+num0+ "   valve_status: "+num1);
                           break;
                       }

                       sendWriteHoldingReg(SerDev_Mid, MIDWAY_MB_SLAVE_ID,(1544+channel_num-1), valve_status);
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set Valve "+ num0 +" to Status "+ num1);
                       break;
                   case 3: //Set Trap 0 to -5 C
                   {
                       list = str.split(" ");
                       num0 = list[2];
                       num1 = list[4];
                       qDebug()<<num0<<num1<<endl;

                       channel_num = num0.toInt();

                       if(channel_num<0 || channel_num>1)
                       {
                           ui->TxtLog->append("脚本第" +  QString::number(ScriptLineNum) + "行解析错误: " + "channel_num: "+num0);
                           break;
                       }

                       QString TEC_temp = "$R0=";
                       TEC_temp += num1;
                       TEC_temp += "\r\n";
                       QByteArray ba = TEC_temp.toLatin1();
                       char *str_setTemp = ba.data();
                       int ret;
                       if((ret=serialWirte((SerDev_TEC_1+(num0.toInt())), str_setTemp, strlen(str_setTemp)))==0)
                       {
                           //MainWindow_log(str_setTemp);
                           ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set Trap "+ num0 +" to "+ num1+" °C");
                       }
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set Trap "+ num0 +" to "+ num1+" °C");
                    }
                       break;
                   case 4: //Set MFC to 0 sccm
                   {
                       list = str.split(" ");
                       num0 = list[3];
                       //qDebug()<<num0<<endl;

                       int set_flow_val = num0.toInt();
                       if(set_flow_val<0 || set_flow_val>500)
                       {
                          // ui->statusBar->showMessage("输入范围超出[0,500] sccm",2000);
                           ui->TxtLog->append("脚本第" +  QString::number(ScriptLineNum) + "行解析错误: " + "MFC flow: "+num0);
                           return ;
                       }
                       quint16 SERVER_ADDR = 0x31;
                       set_flow_val *= 10; //0-5000 数字量 对应 0~500 sccm
                       sendWriteHoldingReg(SerDev_EPC_MFC,MFC_MB_SLAVE_ID,SERVER_ADDR, (quint16) set_flow_val);
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set MFC to "+ num0 +" sccm");
                    }
                       break;
                   case 5: //Set Heater 0 to Status 0
                   {
                       list = str.split(" ");
                       num0 = list[2];
                       num1 = list[5];
                       //qDebug()<<num0<<num1<<endl;
                       channel_num = num0.toInt();
                       float heaterTim = num1.toFloat();

                       if(channel_num<0 || channel_num>1 || heaterTim<0 || heaterTim>15)
                       {
                           ui->TxtLog->append("脚本第" +  QString::number(ScriptLineNum) + "行解析错误: " + "channel_num: "+num0+ "   heaterTime: "+num1);
                           break;
                       }

                       uint16_t sendBuf[2];
                       quint16 startAddr_A = 1554;
                       sendBuf[0] = 1;
                       sendBuf[1] = (uint16_t)(heaterTim*1000/50);
                       sendWriteMultiHoldingReg(SerDev_Mid,0x01,sendBuf, (startAddr_A+channel_num*2), 2);
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"Set Heater "+ num0 +" to Time "+num1);
                   }
                       break;
                   case 6:  //Hotline 0 set to 220 C
                       list = str.split(" ");
                       num0 = list[1];
                       num1 = list[4];
                       qDebug()<<num0<<num1<<endl;
                       break;
                   default:
                       qDebug()<<"脚本内容格式不正确"<<endl;
                       ui->TxtLog->append("["+QTime::currentTime().toString()+"]"+"脚本内容格式不正确");
                       break;
                   }

                   delay(500);

                #if 0
                   QStringList strList = str.split(",", QString::SkipEmptyParts);

                   if(strList.size()!=2) //size MUST==2
                   {
                       ui->statusBar->showMessage("!!!配置文件的第"+QString::number(i+1)+"行格式出错");
                       ui->TxtLog->append("read "+ file.fileName() + " Line:["+QString::number(i+1)+"] error");
                       return;
                   }
                   str0 = strList.at(0);
                   str1 = strList.at(1);

                   /* remove str1's "\r"& "\n" */
                   str1.remove(QChar('\r'), Qt::CaseInsensitive); //remove "\r"
                   str1.remove(QChar('\n'), Qt::CaseInsensitive); //remove "\n"
                   qDebug() <<str1<<endl;

                   ui->TxtLog->append("{"+ str0 +","+ str1+"},");
                   ui->statusBar->showMessage("配置-1:读取成功");
                #endif
                }
            }
            file.close();
        }
}

/*----------------------------------------------*/

void MainWindow::on_BT_Trig_clicked()
{
//    cv.notify_one(); //release semaphore

    qDebug()<<"trig"<<endl;

#if 0
    if(!qthread->isRunning())
    {
        qthread->start();
        is_run = true;
    }
#endif

  /* std thread's trig flag */
    threadTrigFlag = true;
    cv.notify_one();

}
void MainWindow::on_BT_PressStop_clicked()
{
    is_run = false;
    if(qthread->isRunning())
    {
        qthread->quit();
        qthread->wait();
        qDebug()<<"thread quit"<<endl;
    }


    threadTrigFlag = false; //std thread's trig flag
}


















